package cn.jc.springframework.beans.factory.support;

import cn.jc.springframework.beans.BeansException;
import cn.jc.springframework.beans.factory.FactoryBean;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description:
 * @author: JC
 * @date: 2023/4/7 18:01
 */
public class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>();

    protected Object getCachedObjectForFactoryBean(String beanName){
        Object bean = factoryBeanObjectCache.get(beanName);
        return (bean != NULL_OBJECT ? bean : null);
    }

    protected Object getObjectFromFactoryBean(FactoryBean factoryBean,String beanName){
        if(factoryBean.isSingleton()){
            Object obj = factoryBeanObjectCache.get(beanName);
            if(obj == null){
                obj =  doGetObjectFromFactoryBean(factoryBean, beanName);
                this.factoryBeanObjectCache.put(beanName, (obj != NULL_OBJECT)? obj: null);
            }
            return (obj != NULL_OBJECT ? obj : null);
        }

        return doGetObjectFromFactoryBean(factoryBean, beanName);
    }
    private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){
        try {
            return factory.getObject();
        } catch (Exception e) {
            throw new BeansException("FactoryBean threw exception on object["
                    + beanName + "] creation", e);
        }
    }


}
